﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HapperComm
{
    public class ReflecationHelper
    {
        /// <summary>
        /// Datatable转换为List集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tb"></param>
        /// <returns></returns>
        public static List<T> DatatableToList<T>(DataTable tb) where T : class, new()
        {
            List<T> list = new List<T>();

            foreach (DataRow dr in tb.Rows)
            {
                var t = new T();
                foreach (DataColumn item in tb.Columns)
                {
                    var p = t.GetType().GetProperty(item.ColumnName);

                    if (p != null)
                    {
                        p.SetValue(t, dr[item.ColumnName], null);
                    }
                }

                list.Add(t);
            }

            return list;
        }

        /// <summary>
        /// List集合转为DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable ListToDatatable<T>(List<T> list)
        {
            DataTable dt = new DataTable();

            //有多少列？T有多少属性，就有多少列
            var t = typeof(T);
            var ps = t.GetProperties();
            ps.ToList().ForEach(x =>
            {
                DataColumn dc = new(x.Name);
                dt.Columns.Add(dc);
            });

            list.ForEach(x =>
            {
                DataRow dr = dt.NewRow();

                ps.ToList().ForEach(p =>
                {
                    dr[p.Name] = p.GetValue(x);
                });
                dt.Rows.Add(dr);
            });

            return dt;
        }


        /// <summary>
        /// 获取实现的表名（有特性获取特性，没有特性用Model名称）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static string GetEntityTableName<T>()
        {
            var tableName = "";
            var t = typeof(T);
            var obj = t.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), true);

            if (obj != null && obj.Length > 0)
            {
                tableName = ((System.ComponentModel.DataAnnotations.Schema.TableAttribute)obj[0]).Name;
            }
            else
            {
                tableName = t.Name;
            }
            return tableName;
        }


        /// <summary>
        /// 获取Dapper的Insert语句
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string GetDapperInsertSqlString<TEntity>(TEntity entity)
        {
#pragma warning disable CS8602 // 解引用可能出现空引用。
            var t = entity.GetType();
#pragma warning restore CS8602 // 解引用可能出现空引用。

            string tableName = "";
            string filedName = "";
            string fileValue = "";

            tableName = GetEntityTableName<TEntity>();

            //获取属性
            var ps = t.GetProperties();
            ps.ToList().ForEach(p =>
            {
                if (!p.Name.ToLower().Equals("id"))
                {
                    var v = p.GetValue(entity);
                    if (v != null)
                    {
                        filedName += p.Name + ",";
                        fileValue += $"@{p.Name},";
                    }
                }
            });
            string sql = $"insert into {tableName}({filedName.TrimEnd(',')}) values({fileValue.TrimEnd(',')})";
            return sql;
        }

        /// <summary>
        /// 获取Dapper的Update语句
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string GetDapperUpdateSqlString<TEntity>(TEntity entity)
        {
#pragma warning disable CS8602 // 解引用可能出现空引用。
            var t = entity.GetType();
#pragma warning restore CS8602 // 解引用可能出现空引用。

            string tableName = "";
            string fieldValue = "";

            tableName = GetEntityTableName<TEntity>();

            //获取属性
            var ps = t.GetProperties();
            ps.ToList().ForEach(p =>
            {
                if (!p.Name.ToLower().Equals("id"))
                {
                    var v = p.GetValue(entity);
                    if (v != null)
                    {
                        fieldValue += $"{p.Name} = @{p.Name},";
                    }
                }
            });
            string sql = $"update {tableName}　 set {fieldValue.TrimEnd(',')} where id=@id";
            return sql;
        }
    }
}
